
import { _decorator, Component, Node, Sprite, Prefab, Color, Vec3, v3, Vec2, v2 } from 'cc';
import yyComponent from '../../Script/Common/yyComponent';
import GlobalData from '../../Script/Common/GlobalData';
import { GlobalEnum } from '../../Script/GameSpecial/GlobalEnum';
import GlobalPool from '../../Script/Common/GlobalPool';
import { EventType } from '../../Script/GameSpecial/GameEventType';
import Loader from '../../Script/Common/Loader';
import GameData from '../../Script/Common/GameData';
const { ccclass, property } = _decorator;

@ccclass('MiniMap')
export class MiniMap extends yyComponent {

    protected initSub() {
        this.initMapImg();
        this.initRoleIcons();
    }
    protected resetSub() {
        this.resetMapImg();
        this.resetRoleIcons();
    }

    protected onEvents() {
        this.on(EventType.LevelEvent.enemyDead, this.onEnemyDead, this);
    }

    public show() {
        this.node.active = true;
        this.reset();
        this.setMapImg();
        this.setRoleIcons();
        this.onEvents();
    }

    //#region 地图图片
    @property(Node)
    protected mapImgLayer: Node = null;
    @property(Prefab)
    protected mapImgPrefab: Prefab = null;
    /**角色3D坐标到地图坐标的转换比例 */
    protected rate: number = 3;
    protected baseMapWidth: number = 80;
    protected offset: Vec2;
    protected cachePos: Vec3;
    protected initMapImg() {
        GlobalPool.createPool(this.mapImgPrefab.data.name, this.mapImgPrefab);
        this.offset = v2();
        this.cachePos = v3();
    }
    protected resetMapImg() {
        GlobalPool.putAllChildren(this.mapImgLayer, true);
    }
    protected setMapImg() {
        let r = 3;
        let mapIds = [].concat(GlobalData.get(GlobalEnum.myGlobalDataType.matchMap));

        let scope = {
            xMin: 0,
            xMax: 0,
            yMin: 0,
            yMax: 0,
        };
        if (mapIds.length == 1) {
            let str = "map" + mapIds[0];
            this.addImg({ str: str, pos: v3(0, 0, 0) });
            let s = GameData.getData(GlobalEnum.GameDataType.MapData, str).scope;
            scope.xMin = s.xMin;
            scope.xMax = s.xMax;
            scope.yMin = -s.zMax;
            scope.yMax = -s.zMin;
            let rate = this.baseMapWidth / (scope.xMax - scope.xMin);
            this.rate = rate * r;
            this.mapImgLayer.setScale(rate, rate, rate);
            this.offset.x = -(scope.xMax + scope.xMin) * 0.5 * rate * r;
            this.offset.y = -(scope.yMax + scope.yMin) * 0.5 * rate * r;
            this.mapImgLayer.setPosition(this.offset.x, this.offset.y, 0);

        } else {
            if (mapIds[3] == 8) {
                let s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[0]).scope;
                scope.xMax = s.xMax;
                scope.yMin = -s.zMax;
                s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[1]).scope;
                scope.xMin = s.xMin - 47;
                if (scope.yMin > -s.zMax) {
                    scope.yMin = -s.zMax;
                }
                s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[2]).scope;
                scope.yMax = -s.zMin + 45;

                let rate = this.baseMapWidth / (scope.xMax - scope.xMin);
                this.rate = rate * r;
                this.mapImgLayer.setScale(rate, rate, rate);
                this.offset.x = -(scope.xMax + scope.xMin) * 0.5 * rate * r;
                this.offset.y = -(scope.yMax + scope.yMin) * 0.5 * rate * r;
                this.mapImgLayer.setPosition(this.offset.x, this.offset.y, 0);

                this.addImg({ str: "map" + mapIds[0], pos: v3(0, 0, 0) });
                this.addImg({ str: "map" + mapIds[1], pos: v3(-47 * r, 0, 0) });
                this.addImg({ str: "map" + mapIds[2], pos: v3(-22.5 * r, 45 * r, 0) });

            } else {
                let s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[0]).scope;
                scope.xMax = s.xMax;
                scope.yMin = -s.zMax;
                s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[1]).scope;
                scope.xMin = s.xMin - 115;
                if (scope.yMin > -s.zMax) {
                    scope.yMin = -s.zMax;
                }
                s = GameData.getData(GlobalEnum.GameDataType.MapData, "map" + mapIds[2]).scope;
                scope.yMax = -s.zMin + 95;

                let rate = this.baseMapWidth / (scope.xMax - scope.xMin);
                this.rate = rate * r;
                this.mapImgLayer.setScale(rate, rate, rate);
                this.offset.x = -(scope.xMax + scope.xMin) * 0.5 * rate * r;
                this.offset.y = -(scope.yMax + scope.yMin) * 0.5 * rate * r;
                this.mapImgLayer.setPosition(this.offset.x, this.offset.y, 0);

                this.addImg({ str: "map" + mapIds[0], pos: v3(0, 0, 0) });
                this.addImg({ str: "map" + mapIds[1], pos: v3(-115 * r, 0, 0) });
                this.addImg({ str: "map" + mapIds[2], pos: v3(-60 * r, 95 * r, 0) });
            }
        }

    }
    protected addImg(data: { str: string, pos: Vec3 }) {
        Loader.loadBundleRes("UI", "miniMapImg/" + data.str + "/spriteFrame", (res) => {
            let node = GlobalPool.get(this.mapImgPrefab.data.name);
            node.getComponent(Sprite).spriteFrame = res;
            node.setPosition(data.pos);
            this.mapImgLayer.addChild(node);
        });
    }
    //#endregion

    //#region 角色标志
    @property(Node)
    protected roleIconLayer: Node = null;
    @property(Prefab)
    protected roleIconPrefab: Prefab = null;
    protected roleIcons: { [id: number]: { role: Node, icon: Node } } = {};
    protected initRoleIcons() {
        GlobalPool.createPool(this.roleIconPrefab.data.name, this.roleIconPrefab);
        this.roleIcons = {};
    }
    protected resetRoleIcons() {
        GlobalPool.putAllChildren(this.roleIconLayer, true);
        this.roleIcons = {};
    }
    protected setRoleIcons() {
        let str = this.roleIconPrefab.data.name;
        let player = GlobalData.get(GlobalEnum.myGlobalDataType.player);
        let node0 = GlobalPool.get(str);
        node0.getComponent(Sprite).color = Color.GREEN;
        this.roleIconLayer.addChild(node0);
        this.roleIcons[player.Id] = {
            role: player.node,
            icon: node0,
        };
        let enemies = GlobalData.get(GlobalEnum.myGlobalDataType.enemies);
        for (let i = enemies.length - 1; i >= 0; --i) {
            let node = GlobalPool.get(str);
            node.getComponent(Sprite).color = Color.RED;
            this.roleIconLayer.addChild(node);
            this.roleIcons[enemies[i].Id] = {
                role: enemies[i].node,
                icon: node,
            };
        }
        this.roleIconLayer.setPosition(this.offset.x, this.offset.y, 0);
    }
    protected removeRoleIcon(roleId: number) {
        let data = this.roleIcons[roleId];
        if (!!data) {
            GlobalPool.put(data.icon);
        }
        delete this.roleIcons[roleId];
    }
    protected updateIcons(dt: number) {
        for (let key in this.roleIcons) {
            this.roleIcons[key].role.getPosition(this.cachePos);
            this.cachePos.x *= this.rate;
            this.cachePos.z *= -this.rate;
            this.roleIcons[key].icon.setPosition(this.cachePos.x, this.cachePos.z, 0);
        }
    }

    //#endregion

    protected onEnemyDead(enemy) {
        this.removeRoleIcon(enemy.Id);
    }

    update(dt) {
        this.updateIcons(dt);
    }
}
